<?php
	class DynamicPage extends AppModel
	{
		var $name = "DynamicPage";
		private $pagesInfoArray = false;
		var $additionalFields = array("fieldOptions");
		
		function fieldOptions($page)
		{
			$field = $page[$this->alias]['field'];
			$options = cri("CustomField")->field("options",array("name"=>$field));
			return $options;
		}
		function getPagesField($refresh = false)
		{
			$pagesFields = $this->getPageFieldsInfo($refresh);
			$fields = Set::extract('{n}.'.$this->alias.'.field',$pagesFields);
			return $fields;
		}
		function getFieldUrlPrefix($field)
		{
			if(!isset($this->pageFieldsPrefixMap))
			{
				$pageFields = $this->getPageFieldsInfo($field);
				$this->pageFieldsPrefixMap = Set::combine($pageFields,'{n}.'.$this->alias.'.field','{n}.'.$this->alias.'.prefix');
			}
			return $this->pageFieldsPrefixMap[$field];
		}
		function getPageFieldsInfo($refresh = false)
		{
			if($this->pagesInfoArray == false || $refresh)
			{
				$cacheKey  = "dynamic_pages_fields";
				GigaCache::set(array("duration"=>"+1 hour","path"=>CACHE));
				$pagesFields = GigaCache::read($cacheKey);
				if(!is_array($pagesFields) || $refresh)
				{
					$pagesFields = $this->find('all');
					GigaCache::write($cacheKey,$pagesFields);
				}
				$this->pagesInfoArray = $pagesFields;
			}
			return $this->pagesInfoArray;
		}
		function initialize()
		{
			$this->fieldProperties = array(
				'name'=>array('tooltip'=>"For internal system name.",'group'=>"add",'validate'=>array(array("rule"=>"/^\w+$/",'required'=>true,'empty'=>false,'message'=>__("Please enter numbers,alphabtes and underscores only.")),
																		array("rule"=>"unique","message"=>__("This field name already exists.")))),
				'field'=>array("validate"=>array(array("rule"=>"validCustomField",'message'=>__("Please select a valid value."),'required'=>true,'empty'=>false),
												array("rule"=>"unique",'message'=>__("Configuration for this field is saved already."),'required'=>true,'empty'=>false)),'group'=>"add",'empty'=>__("-Select-")),
				'prefix'=>array("tooltip"=>"To be used in url, like city",'group'=>"add",'validate'=>array(array("rule"=>"validUrlPrefix",'message'=>__("This url prefix is being used internally to parse other requests.Please use some other prefix."),'allowEmpty'=>false),array("rule"=>"/^\w+$/",'required'=>true,'empty'=>false,'message'=>__("Please enter numbers,alphabtes and underscores only.")),
																		array("rule"=>"unique","message"=>__("This field name already exists.")),)),
				'title'=>array("tooltip"=>__("To prefixed in title tag.Use :title to put active page name in title."),'group'=>"add"),
				'page_title'=>array("tooltip"=>__("For home page of field.Use :title  to put active page name in title."),'group'=>"add"),
			);
			parent::initialize();
		}
		function isPageField($field)
		{
			return in_array($field,$this->getPagesField());
		}
		function getPageInfo($field)
		{
			$pages = $this->getPageFieldsInfo();
			$pageInfo = null;
			foreach($pages as $page)
			{
				if($page[$this->alias]['field'] == $field)
				{
					$pageInfo = $page;
					break;
				}
			}
			return $pageInfo;
		}
		function getAsGigaActionPages()
		{
			$pages = array();
			foreach($this->getPagesField() as $field)
			{
				$label = sprintf(__('%s page'),Inflector::humanize($field));
				$page = new GigaAction(
				$this->getPageId($field),
				$label,
					array("controller"=>"dynamic_pages","action"=>"page",$field)
				);
				$pages[$field] = $page;
			}
			return $pages;
		}
		
		function getPageId($field)
		{
			return 'dynamicpage_'.$field;	
		}
		function getCacheFieldName($field)
		{
			return "cache_".$field;
		}
		function setModelsScopes($field,$value)
		{
			$models = array("Listing","ListCategory","Review","ReviewComment","ListingAsset",'Tags.TaggedItem');
			foreach($models as $model)
			{
				$cacheField = $this->getCacheFieldName($field);
				$ModelInst = cri($model);
				if($ModelInst->hasField($cacheField) == false)
				{
					continue;	
				}
				$scope = array($ModelInst->alias.'.'.$cacheField." like" => "%-".$value."-%");
				$scopeName = $cacheField.'_scope';
				$ModelInst->setScope($scope,$scopeName);
				$ModelInst->cacheIgnorerScopes[] = $scopeName;
			}
		}
		
		function getFieldsList()
		{
			$CustomFieldModel = cri("CustomField");
			$fieldsList = array();
			$types = $CustomFieldModel->getFieldProperty('type','options');
			$fields = $CustomFieldModel->find('all',array("recursive"=>-1,'conditions'=>array("type"=>array("select","radio",
						"multipleSelect","multipleCheckbox"))));
			foreach($fields as $field)
			{
				$fieldsList[$field[$CustomFieldModel->alias]['name']] = $field[$CustomFieldModel->alias]['label'].'('.$types[$field[$CustomFieldModel->alias]['type']].')';	
			}
			return $fieldsList;
		}
		
		function validCustomField($data)
		{
			$value = array_shift($data);	
			return in_array($value,array_keys($this->getFieldsList()));
		}
		
		function afterSave($created)
		{
			parent::afterSave($created);
			App::import("Vendor","DynamicPageRoutes");
			$routes = new DynamicPageRoutes;
			$routes->savePagesPath($this);
			$this->getPageFieldsInfo(true);
		}
		
		function afterDelete()
		{
			parent::afterDelete();
			App::import("Vendor","DynamicPageRoutes");
			$routes = new DynamicPageRoutes;
			$routes->savePagesPath($this);
			$this->getPageFieldsInfo(true);
		}
		/**
		 * Return a url prefix that will be appeneded to url's while making link
		 * Eg /city/la-1
		 * @param unknown_type $field
		 * @param unknown_type $value
		 */
		function getPagePerfixUrl($field,$value)
		{
			$route = false;
			$pageInfo  = $this->getPageInfo($field);
			if($pageInfo && isset($pageInfo[$this->alias]['fieldOptions'][$value]))
			{
				$slug = $this->getUrlPrefixSlug($field,$value,$pageInfo[$this->alias]['fieldOptions'][$value]);
				$route = String::insert(DynamicPageRoutes::ROUTE_PREFIX,array("url_prefix"=>$pageInfo[$this->alias]['prefix'],'dynamicFieldValue'=>$slug));
			}
			return $route;
		}
		private function getUrlPrefixSlug($field,$value,$label="")
		{
			$slugFormat = $this->getSlugFormat($field);
			$label = Inflector::slug($label);
			$insert = array("value"=>$value,'label'=>$label);
			$slug = String::insert($slugFormat,$insert);
			return $slug;
		}
		private function getSlugFormat($field)
		{
			//see extractOptionValueFromSlug before change.
			//Changing this can change extractOptionValueFromSlug behavior
			return ":label-:value";
		}
		
		function extractOptionValueFromSlug($field,$slug)
		{
			$pageInfo  = $this->getPageInfo($field);
			$options = $pageInfo[$this->alias]['fieldOptions'];
			//using - as getSlugFormat uses - as sepreator
			$slugParts = explode("-",$slug);
			$slugFormatsParts = explode("-",$this->getSlugFormat($field));
			//key is being checked from back as label slug might contain - within itself.
			//this logic will only work only if :value is last part of the string.
			$valueKey = array_search(':value',array_reverse($slugFormatsParts));
			$valueKey = (count($slugParts)-1) - $valueKey;
			$value = null;
			if(isset($slugParts[$valueKey]))
			{
				$value = $slugParts[$valueKey];
			}
			return $value;
		}
		
		function getPageTitle($field,$value)
		{
			$pageInfo  = $this->getPageInfo($field);
			return $pageInfo[$this->alias]['fieldOptions'][$value];
		}
		
		function validUrlPrefix($data)
		{
			$prefix = $data['prefix'];
			$testUrl = "/$prefix/test";
			$dispatcher = new Dispatcher();
			$params = $dispatcher->parseParams($testUrl);
            //case of editing the dynamic page.
            if(isset($params['dynamicField']) && $this->data[$this->alias]['field'] == $params['dynamicField'])
            {
              return true;
            }
			$plugin = Inflector::camelize($params['plugin']);
			$controller = Inflector::camelize($params['controller']);
			$return = true;
			if($prefix == "admin")
			{
				$return = false;
			}
			else if($plugin)
			{
				if( App::import('Controller',$plugin.'.'.$controller)  || App::import('Controller',$plugin.'.'.$plugin))
				{
					$return = false;
				}
			}else if(App::import("Controller",$controller))
			{
				$return = false;
			}
			return $return;
		}
	}
?>